package middleware

import (
	"strconv"
	"strings"
	"time"

	utils "hermestrans/basis/utils"

	"github.com/gin-gonic/gin"
	uuid "github.com/satori/go.uuid"
	"github.com/sirupsen/logrus"
)

func Trace() gin.HandlerFunc {
	return func(c *gin.Context) {
		var (
			traceId string
			code    int
			start   time.Time
			cost    int64
		)
		start = time.Now() //打点开始时间
		headers := c.Request.Header
		if value, ok := headers["Trace-Id"]; ok {
			traceId = value[0]
		} else {
			newId := uuid.NewV4() //产生一个uuid作为traceid
			traceId = newId.String()
		}
		c.Set("trace_id", traceId)

		c.Next()
		//获得resp
		resp, ok := c.Get(utils.PrefixResponse)
		if ok {
			if detailRes, ok := resp.(utils.DetailResponse); ok {
				code = detailRes.Code
			}
		}

		//auth 获取
		authInterface, ok := c.Get("auth")
		auth := &utils.Auth{}
		if ok {
			auth, _ = authInterface.(*utils.Auth)
		}
		//request url
		url := c.Request.URL.Path
		//fetch params
		params, ok := c.Get(utils.PrefixParams)
		if !ok {
			params = ""
		}

		cost = time.Since(start).Milliseconds()
		status := strconv.Itoa(c.Writer.Status())
		remoteIp := c.ClientIP()
		logrus.WithFields(logrus.Fields{"trace_id": traceId,
			"user":           auth.Name,
			"role":           auth.Role,
			"cost":           cost,
			"content_length": c.Writer.Size(),
			"url":            url,
			"params":         params,
			"code":           code,
			"status":         status,
			"remote_ip":      remoteIp}).Info("GIN_request")

		errs := c.Errors.Errors()
		if errs != nil && len(errs) > 0 {
			logrus.Error("error ", "trace_id", traceId, "err", strings.Join(errs, ","))
			return
		}
	}
}
